<?php
/**
 * @author Pramod Thakur
 * This Class provides track all events in a table and then later user cron job or else to process all those events which is being tracked
*/
class Tracker {
	
	/**
	 * Track all events in a table then precess it one by one
	 * 
	 * @param $class, $function,
	 *			$args, $type
	 */
	public static function saveTrackEvent($class, $function, $args = array(), $type = 'email') {
		// check if class name or function name passed or not
		if ($class == '' || $function == '') {
			throw new Exception ( "Class name and class's function name must be declared !" );
		}
		// check if class are exists or not
		if (! class_exists ( $class )) {
			throw new Exception ( "There is no '$class' exists in the system!" );
		}
		// check if class have define function or not
		if (! method_exists ( new $class (), $function )) {
			throw new Exception ( "There is no function '$function' defined in class '$class' !" );
		}
		// process the arguments list and check for empty keys if exists them empty that key value pair
		foreach ( $args as $key => $val ) {
			// check if key is empty or not
			if (trim ( $key ) == '') {
				// distroy the key value pair
				unset ( $args [trim ( $key )] );
				continue;
			}
		}
		$args = count ( $args ) ? serialize ( $args ) : '';
		try {
			// add the tracker record
			$objTrackerAdd = getDb ( 'tracker', 'add' );
			$objTrackerAdd->set ( "class||$class", "function||$function", "args||$args", "type||$type" );
			// return the trackerId
			return $objTrackerAdd->getLastInsertedId ();
		} catch ( Exception $ex ) {
			throw $ex;
		}
	}
	
	/**
	 * Process all the track events
	 * 
	 * @param
	 *			$type
	 */
	public static function processTrackEvents($type = '') {
		
		// set the default where clause
		$whereClause = array (
				'processed||N',
				'quantity||500' 
		);
		// check if type is set or not
		if ($type) {
			$whereClause [] = "type||$type";
		}
		// get all unprocessed track events
		$objTrackers = getMultiple ( 'tracker', $whereClause );
		foreach ( $objTrackers () as $objTracker ) {
			// get class name
			$class = trim ( $objTracker->getClass () );
			// get function name
			$function = trim ( $objTracker->getFunction () );
			// check if class or function name empty then continue the loop
			if ($class == '' || $function == '') {
				continue;
			}
			// check if class are exists or not
			if (! class_exists ( $class )) {
				continue;
			}
			// check if class have define function or not
			if (!method_exists ( new $class (), $function )) {
				continue;
			}
			
			try {
				// get the function's arguments lists
				$args = trim ( $objTracker->getArgs () ) != '' ? unserialize ( trim ( $objTracker->getArgs () ) ) : array ();
				if (count ( $args ) > 0) {
					// make function arugment then call the function
					$argsStr = str_replace ( '"', '\"', implode ( '<--- ei --->', $args ) );
					$argsStr = '"' . str_replace ( '<--- ei --->', '", "', $argsStr ) . '"';
					// call the class and process the tracking details
					$objClass = new $class();
					eval ( '$objClass->$function( ' . $argsStr . ' );' );
				} else {
					// call the class and process the tracking details
					$objClass = new $class();
					eval ( '$class->$function();' );
				}
				// update the tracker status
				$objTracker->update ( 'processed||Y' );
			} catch ( Exception $ex ) {
				describe($ex);
				continue;
				// throw $ex;
			}
		}
	}
}